﻿using System;
using GeoAPI.Geometries;
using NetTopologySuite.Geometries;
using NetTopologySuite.Index.Strtree;

namespace NetTopologySuite.Algorithm
{
	public class SIRtreePointInRing : IPointInRing
	{
		public SIRtreePointInRing(ILinearRing ring)
		{
			this._ring = ring;
			this.BuildIndex();
		}

		private void BuildIndex()
		{
			this._sirTree = new SIRtree<LineSegment>();
			Coordinate[] coordinates = this._ring.Coordinates;
			for (int i = 1; i < coordinates.Length; i++)
			{
				if (!coordinates[i - 1].Equals(coordinates[i]))
				{
					LineSegment lineSegment = new LineSegment(coordinates[i - 1], coordinates[i]);
					this._sirTree.Insert(lineSegment.P0.Y, lineSegment.P1.Y, lineSegment);
				}
			}
		}

		public bool IsInside(Coordinate pt)
		{
			this._crossings = 0;
			foreach (LineSegment seg in this._sirTree.Query(pt.Y))
			{
				this.TestLineSegment(pt, seg);
			}
			return this._crossings % 2 == 1;
		}

		private void TestLineSegment(Coordinate p, LineSegment seg)
		{
			Coordinate p2 = seg.P0;
			Coordinate p3 = seg.P1;
			double x = p2.X - p.X;
			double num = p2.Y - p.Y;
			double x2 = p3.X - p.X;
			double num2 = p3.Y - p.Y;
			if ((num > 0.0 && num2 <= 0.0) || (num2 > 0.0 && num <= 0.0))
			{
				double num3 = (double)RobustDeterminant.SignOfDet2x2(x, num, x2, num2) / (num2 - num);
				if (0.0 < num3)
				{
					this._crossings++;
				}
			}
		}

		private readonly ILinearRing _ring;

		private SIRtree<LineSegment> _sirTree;

		private int _crossings;
	}
}
